package com.tanhua.dubbo.server.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.pojo.Identification;
import com.tanhua.dubbo.server.pojo.Option;
import com.tanhua.dubbo.server.pojo.Question;
import com.tanhua.dubbo.server.pojo.TestSoulQuestionnaire;
import com.tanhua.dubbo.server.vo.Answer;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;

@Service(version = "1.0.0")
@Slf4j
public class TestSoulApiImpl implements TestSoulApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    /**
     * 实现功能:获取系统推荐的灵魂问卷列表
     *
     * @param userId
     */
    @Override
    public List<TestSoulQuestionnaire> getTestSoulQuestionnaires(Long userId) {
        Query query = new Query().limit(10);
        List<TestSoulQuestionnaire> list = mongoTemplate.find(query, TestSoulQuestionnaire.class);
        return list;
    }

    /**
     * 实现功能:获取对应灵魂问卷的试题列表
     *
     * @param questionIds
     */
    @Override
    public List<Question> getQuestions(List<ObjectId> questionIds) {
        Query query = Query.query(Criteria.where("id").in(questionIds));
        List<Question> list = mongoTemplate.find(query, Question.class);
        return list;
    }

    /**
     * 实现功能:获取对应试题的选项列表
     *
     * @param optionIds
     */
    @Override
    public List<Option> getOptions(List<ObjectId> optionIds) {
        Query query = Query.query(Criteria.where("id").in(optionIds));
        List<Option> list = mongoTemplate.find(query, Option.class);
        return list;
    }

    /**
     * 查看问卷报告
     *
     * @param reportId
     * @return
     */
    @Override
    public Identification getIdentification(String reportId) {
        return mongoTemplate.findById(new ObjectId(reportId), Identification.class);
    }

    /**
     * 提交问卷
     *
     * @param answers
     * @param userId
     * @return
     */
    @Override
    public Identification postTestSoul(Answer[] answers, Long userId) {
        //创建一个灵魂检测报告的对象
        Identification identification = new Identification();
        identification.setId(ObjectId.get());
        identification.setUserId(userId);
        //设置查询条件
        Query query = new Query();
        //获取所有的灵魂测试问卷
        List<TestSoulQuestionnaire> lists = mongoTemplate.find(query, TestSoulQuestionnaire.class);
        //遍历灵魂测试问卷,找到对应的问卷id,设置到报告对象里面
        for (TestSoulQuestionnaire list : lists) {
            List<ObjectId> questionIds = list.getQuestionIds();
            for (ObjectId questionId : questionIds) {
                if (StrUtil.equals(questionId.toHexString(), answers[0].getQuestionId())) {
                    identification.setQuestionnaireId(list.getId());
                    break;
                }
            }
        }
        //设置维度的集合
        List<Integer> dimensions = new ArrayList<>();
        dimensions.add(0);
        dimensions.add(0);
        dimensions.add(0);
        dimensions.add(0);
        //计算维度 维度:0外向,1判断,2抽象,3理性.
        Integer sumDimension = 0;
        //获取所有的选项的id
        List<ObjectId> listOption = new ArrayList<>();
        for (Answer answer : answers) {
            listOption.add(new ObjectId(answer.getOptionId()));
        }
        //查找所有的选项的信息
        Query queryOptionId = Query.query(Criteria.where("id").in(listOption));
        List<Option> options = mongoTemplate.find(queryOptionId, Option.class);
        for (Option option : options) {
            List<Integer> ds = option.getDimensions();
            //设置每个维度的值和
            dimensions.set(0, dimensions.get(0) + ds.get(0));
            dimensions.set(1, dimensions.get(1) + ds.get(1));
            dimensions.set(2, dimensions.get(2) + ds.get(2));
            dimensions.set(3, dimensions.get(3) + ds.get(3));
        }
        //求平均的维度值
        for (int i = 0; i < dimensions.size(); i++) {
            dimensions.set(i, dimensions.get(i) / options.size());
            sumDimension = sumDimension + dimensions.get(i);
        }
        identification.setDimensions(dimensions);
        //设置报告生成时间
        identification.setCreated(System.currentTimeMillis());

        Integer dValue = sumDimension / 4;
        Query querySimilar = new Query();
        //查找所有的报告信息
        List<Identification> identifications = mongoTemplate.find(querySimilar, Identification.class);
        //查找与自己相似的用户
        Set<Long> listUser = new TreeSet<>();
        //遍历所有的报告
        for (Identification id1 : identifications) {
            List<Integer> dimensions1 = id1.getDimensions();
            Integer sum = 0;
            for (Integer integer : dimensions1) {
                //获取维度值的和
                sum = sum + integer;
            }
            //每份报告的平均维度值
            sum = sum / 4;
            List<Long> similarYou = id1.getSimilarYou();
            List<Long> mySimilarYou = identification.getSimilarYou();
            //设置相似的用户的id
            if (sum / 8 == dValue / 8) {
                boolean flag = true;
                if (CollUtil.isEmpty(similarYou)) {
                    similarYou = new ArrayList<>();
                }
                for (Long aLong : similarYou) {
                    if (aLong == userId || id1.getUserId() == userId) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    similarYou.add(userId);
                }
                flag = true;
                if (CollUtil.isEmpty(mySimilarYou)) {
                    mySimilarYou = new ArrayList<>();
                }
                for (Long aLong : mySimilarYou) {
                    if (aLong == id1.getUserId() || id1.getUserId() == userId) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    mySimilarYou.add(id1.getUserId());
                }
            }
            id1.setSimilarYou(similarYou);
            identification.setSimilarYou(mySimilarYou);
        }
        return identification;
    }

    /**
     * 获取最新的问卷的报告id
     *
     * @param userId
     * @param id
     * @return
     */
    @Override
    public String searchReportId(Long userId, ObjectId id) {
        Query query = Query.query(Criteria.where("userId").is(userId).and("questionnaireId").is(id)).with(Sort.by(Sort.Order.desc("created")));
        Identification identification = mongoTemplate.findOne(query, Identification.class);
        if (ObjectUtil.isEmpty(identification)) {
            return null;
        }
        return identification.getId().toHexString();
    }

    /**
     * 保存报告信息
     *
     * @param identification
     */
    @Override
    public void save(Identification identification) {
        mongoTemplate.save(identification);
    }

    /**
     * 根据问卷id获取问卷级别
     *
     * @param questionnaireId
     * @return
     */
    @Override
    public String getLevel(ObjectId questionnaireId) {
        Query query = Query.query(Criteria.where("id").is(questionnaireId));
        TestSoulQuestionnaire testSoulQuestionnaire = mongoTemplate.findOne(query, TestSoulQuestionnaire.class);
        return testSoulQuestionnaire.getLevel();
    }

}
